<?php
/**
 * User: b179a9
 * Date: 9/29/11
 * Time: 6:02 PM
 */

namespace Managers;

class Comments extends BaseManager
{
    const TABLE = '\Catalog\Comments';
    protected $__table = self::TABLE;

    public function create(array $values, $user)
    {
        $entity = new \Catalog\Comments();
        $newsRef = $this->_em->getReference(News::TABLE, $values['news']);
        if ($newsRef) {
            $entity->setIsDel(false);
            $entity->setNews($newsRef);
            $entity->setEmail($user['email']);
            $entity->setText($values['text']);
            $entity->setCreatedAt(new \DateTime());
            $entity->setIsBlocked(false);
            if (isset($values['parent']) && $values['parent']) {
                $parentRef = $this->_em->getReference($this->__table, $values['parent']);
                $entity->setParent($parentRef);
            }
            $userRef = $this->_em->getReference(Users::TABLE, $user['id']);
            $entity->setUser($userRef);
            $this->_em->persist($entity);
            $this->flush();
            return $entity;
        }
        return false;
    }

    public function getCountByArticles(array $articles)
    {
        if (!count($articles)) {
            return $articles;
        }
        $articlesId = Utils::rebuildArray($articles);
        $qb = $this->createQueryBuilder()
            ->select('c, partial n.{id}, count(c.id) as total')
            ->addGroupBy('n.id');
        $qb->andWhere($qb->expr()->in('n.id', $articlesId));
        $res = $qb->getQuery()->getArrayResult();
        return $res;
    }

    public function createQueryBuilder()
    {
        $qb = $this->_em->createQueryBuilder()
            ->select('c, partial n.{id, title}, partial p.{id}, partial u.{id, email, name}')
            ->from($this->__table, 'c')
            ->join('c.news', 'n')
            ->join('c.user', 'u')
            ->leftJoin('c.parent', 'p')
            ->andWhere('n.isDel = 0')
            ->andWhere('c.isDel = 0')
            ->andWhere('u.isDel = 0');
        return $qb;
    }

    public function getTreeList($newsId)
    {
        $qb = $this->createQueryBuilder()
            ->andWhere('n.id = :news')->setParameter('news', $newsId)
            ->andWhere('c.parent is null');
        $res = $qb->getQuery()->getArrayResult();
        $res = $this->addChildren($res);
        $res = $this->addRatings($res);
        return $res;
    }

    public function addRatings($comments)
    {
        $ratingManager = new CommentsRating();
        $comments = $ratingManager->addRatings($comments);
        return $comments;
    }

    public function getAllComments($newsId)
    {
        $qb = parent::createQueryBuilder();
        $qb->select('c, partial n.{id}')
            ->from($this->__table, 'c')
            ->join('c.news', 'n')
            ->andWhere('n.id = :news')->setParameter('news', $newsId);
        $res = $qb->getQuery()->getArrayResult();
        return $res;
    }

    public function addChildren(array $comments)
    {
        if (!count($comments)) {
            return $comments;
        }
        $qb = $this->createQueryBuilder();
        $commentsIds = Utils::rebuildArray($comments);
        $qb->andWhere($qb->expr()->in('c.parent', $commentsIds));
        $children = $qb->getQuery()->getArrayResult();
        if (count($children)) {
            $children = $this->addChildren($children);
        }
        foreach ($comments as &$comment) {
            $comment['children'] = array();
            foreach ($children as $child) {
                if ($child['parent']['id'] == $comment['id']) {
                    $comment['children'][] = $child;
                }
            }
        }

        return $comments;
    }

    public function getById($id)
    {
        $qb = $this->createQueryBuilder()
            ->andWhere('c.id = :id')->setParameter('id', $id);
        $res = $qb->getQuery()->getArrayResult();
        return count($res) ? $res[0] : false;
    }

    public function getMostCommentable($limit = 10)
    {
        $now = new \DateTime();
        $now->sub(new \DateInterval('P1W'));

        $qb = $this->createQueryBuilder()
            ->select('count(n.id) as total, n.id as id')
            ->addGroupBy('n.id')
            ->addOrderBy('total', 'DESC')
            ->andWhere('c.createdAt >= :date')->setParameter('date', $now)
            ->setMaxResults($limit);

        $res = $qb->getQuery()->getArrayResult();
        return $res;
    }

    public function updateByAdmin(array $values)
    {
        $entity = $this->find($values['id']);
        /* @var \Catalog\Comments $entity */
        $entity->setText($values['text']);
        $this->_em->persist($entity);
        $this->flush();
        return $entity;
    }

    public function deleteByAdmin($id)
    {
        $entity = $this->find($id);
        /* @var \Catalog\Comments $entity */
        $entity->setIsBlocked(true);
        $this->_em->persist($entity);
        $this->flush();
        return $entity;
    }

    public function multiplyDeletes($entities)
    {
        foreach ($entities as $entity) {
            /* @var \Catalog\Comments $entity */
            $entity->setIsBlocked(true);
            $this->_em->persist($entity);
        }
        $this->flush();
    }

}
